/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.namabank.util;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import org.apache.commons.lang.RandomStringUtils;

/**
 * [%{}%]: hằng
 * [%&fgdf&%]: biến
 * [%$_auto_gen_id_$%] bien ngau nhien
 * @author Hienforis
 */
public class TemplateFile {

    protected static String startTagRead = "<!%start%!>";
    protected static String endTagRead = "<!%end%!>";

    protected static String startTagResource = "[%{";
    protected static String endTagResource = "}%]";

    protected static String startTagParam = "[%&";
    protected static String endTagParam = "&%]";

    protected static String startTagAutoGen = "[%$_";
    protected static String endTagAutoGen = "_$%]";

    protected static String startTagIf = "<!--if {0}-->";
    protected static String endTagIf = "<!--{0} endif-->";
    protected static String startTagInclude = "[%@include file=@";
    protected static String endTagInclude = "@%]";

    private static String workingPath = "";
    private static String contextpath = "";
    public static Boolean developing = false;

    private HashMap<String, String> listAutoKey = new HashMap<String, String>();
    private static String defaultTemplateName = "";
    private static org.jsoup.nodes.Element config = null;
    //<editor-fold defaultstate="collapsed" desc="Biến cục bộ">
    //</editor-fold>

    public TemplateFile() {}

    //<editor-fold defaultstate="collapsed" desc="Những hàm static">
    /**
     * Khởi tạo cho biến static
     */
    static org.jsoup.nodes.Element getConfig(){
        if(config == null){
            config = ConfigurationUtils.getJsoupConfig("template-config.xml");
            defaultTemplateName = config.select("template[default=true]").attr("name");
        }
        return config;
    }

    public static String getFilePathByName(String templateName, String keyName){
        if(getConfig() == null)
            return null;
        if(templateName == null)
            templateName =defaultTemplateName;
        return config.select("template[name=" + templateName + "]>file[name=" + keyName + "]").html().trim();
    }

    public static void setWorkingPath(String s) {
        workingPath = s;
        if(workingPath == null)
            workingPath = "";
    }
    public static void setContextPath(String s) {
        contextpath = s;
        if(contextpath == null)
            contextpath = "";
    }
    //</editor-fold>

    /**
     * Đoc file html, gán chuỗi resource, gán chuỗi ngẫu nhiên
     * @param params
     * @return
     */
    private String readTemplateHTML(HashMap<String, Object> params) {
        FileInputStream fr;
        String charset = (String)params.get("charset");
        String absolute_source_path = (String)params.get("absolute_source_path");
        if(absolute_source_path == null){
            String relative_source_path = (String)params.get("relative_source_path");
            if(relative_source_path == null)
                return null;
            absolute_source_path = workingPath + "/" + relative_source_path;
        }
        try {
            fr = new FileInputStream(absolute_source_path);
            BufferedReader br = new BufferedReader(new InputStreamReader(fr, charset));
            StringBuilder sb = new StringBuilder();

            String eachLine = br.readLine();
            boolean startRead = false;
            boolean endRead = false;
            int index1, index2;
            String lineSeparater = System.getProperty("line.separator");
            while (eachLine != null) {
                if (!startRead) {
                    index1 = eachLine.indexOf(startTagRead);
                    if (index1 >= 0) {
                        eachLine = eachLine.substring(index1 + startTagRead.length());
                        startRead = true;
                    }
                }
                if (startRead) {
                    index1 = eachLine.indexOf("//");
                    if (index1 >= 0) {
                        if (index1 == 0 || (index1 > 0 && eachLine.charAt(index1 - 1) != ':')) {
                            eachLine = eachLine.substring(0, index1);
                        }
                    }
                    index1 = eachLine.indexOf(endTagRead);
                    if (index1 >= 0) {
                        eachLine = eachLine.substring(0, index1);
                        endRead = true;
                    }
                    //-----------------------------------
                    index1 = eachLine.indexOf(startTagResource);
                    while (index1 >= 0) {
                        index2 = eachLine.indexOf(endTagResource, index1);
                        if (index2 > 0) {
                            String rstext = eachLine.substring(index1 + startTagResource.length(), index2);
                            if (rstext.equals("contextpath")) {
                                eachLine = eachLine.replace(startTagResource + rstext + endTagResource, contextpath);
                            } else {
                                eachLine = eachLine.replace(startTagResource + rstext + endTagResource, ResourceUtil.getString(rstext));
                            }
                            index2 = index1 + 1;
                        } else {
                            index2 = index1 + startTagResource.length();
                        }
                        index1 = eachLine.indexOf(startTagResource, index2);
                    }
                    //-----------------------------------
                    index1 = eachLine.indexOf(startTagAutoGen);
                    while (index1 >= 0) {
                        index2 = eachLine.indexOf(endTagAutoGen, index1);
                        if (index2 > 0) {
                            String rstext = eachLine.substring(index1 + startTagAutoGen.length(), index2);
                            if(rstext.length() == 0 || !listAutoKey.containsKey(rstext))
                                listAutoKey.put(rstext, "h" + RandomStringUtils.randomAlphanumeric(10));
                            eachLine = eachLine.replace(startTagAutoGen + rstext + endTagAutoGen, listAutoKey.get(rstext));
                            index2 = index1 + 1;
                        } else {
                            index2 = index1 + startTagAutoGen.length();
                        }
                        index1 = eachLine.indexOf(startTagAutoGen, index2);
                    }
                    //------------------------------------------------------------
                    index1 = eachLine.indexOf(startTagInclude);
                    if (index1 >= 0) {
                        index2 = eachLine.indexOf(endTagInclude);
                        if (index2 > 0) {
                            String rstext = eachLine.substring(index1 + startTagInclude.length(), index2);
                            params.put("relative_source_path", rstext);
                            eachLine = eachLine.replace(startTagInclude + rstext + endTagInclude, readTemplateHTML(params));
                        }
                    }

                    sb.append(eachLine).append(lineSeparater);

                }
                if (endRead) {
                    break;
                }
                eachLine = br.readLine();
            }
            fr.close();
          //  System.out.println(sb.toString());
            return sb.toString();
        } catch (Exception ex) {
            return ex.getMessage();
        }
    }

    /**
     * Đọc file html dựa vào đường dẫn tương đối
     * @param filepath
     * @return
     */
    public String readTemplateHTML(String filepath) {
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("relative_source_path", filepath);
        params.put("charset", "UTF-8");
        return readTemplateHTML(params);
    }

    /**
     * Đọc file html dựa vào tên tempate và tên key (định nghĩa trong file
     * tempate-config.xml)
     * @param templateName
     * @param keyName
     * @return
     */
    public String readTemplateHTML(String templateName, String keyName){
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("relative_source_path", getFilePathByName(templateName, keyName));
        params.put("charset", "UTF-8");
        return readTemplateHTML(params);
    }

    /**
     * Thay thế biến trong đoạn text
     * @param source đoạn text chứ chuỗi cần thay thế
     * @param params bảng các biến
     * @return
     */
    public String replaceByParams(String source, HashMap params) {
        if (source == null || source.length() == 0) {
            return "";
        }
        if (params == null) {
            return source;
        }
        String res = source;

        int index2;
        int index1 = res.indexOf(startTagParam);
        while (index1 >= 0) {
            index2 = res.indexOf(endTagParam, index1);
            if (index2 > index1) {
                String param = res.substring(index1 + startTagParam.length(), index2);

                if (param.equals("contextpath")) {
                    res = res.replace(startTagParam + param + endTagParam, contextpath);
                } else if (params.containsKey(param) && params.get(param) != null) {
                    res = res.replace(startTagParam + param + endTagParam, params.get(param).toString());
                } else if (params.containsKey("default")) {
                    res = res.replace(startTagParam + param + endTagParam, params.get("default").toString());
                } else {
                    res = res.replace(startTagParam + param + endTagParam, "");
                }
                index2 = index1 + 1;
            } else {
                index2 = index1 + startTagParam.length();
            }

            index1 = res.indexOf(startTagParam, index2);
        }

        return res;
    }
    
    /**
     * @return the listAutoKey
     */
    public HashMap<String, String> getListAutoKey() {
        return listAutoKey;
    }

    /**
     * @return the defaultTemplateName
     */
    public static String getDefaultTemplateName() {
        return defaultTemplateName;
    }

    /**
     * @param aDefaultTemplateName the defaultTemplateName to set
     */
    public static void setDefaultTemplateName(String aDefaultTemplateName) {
        defaultTemplateName = aDefaultTemplateName;
    }
}
